package com.example.controller;

import com.example.entity.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * rest风格接口
 * 测试数据库连接以及增删改查
 */
@RestController
public class UserController {

    /* 数据库配置 */
    private static final String DB_URL = "jdbc:mysql://192.168.110.72:3306/java";
    /* 数据库用户名 */
    private static final String DB_USER = "root";
    /* 数据库密码 */
    private static final String DB_PASSWORD = "root";

    // 模拟用户数据库 这里使用的是系统内存，关闭系统数据就会丢失 设置为map类型，key位字符串，value为字符串
    private Map<String, String> userDatabase = new HashMap<>();

    /**
     * 测试使用数据库写入数据
     */
    @PostMapping("/register2")
    /* 定义参数名称是user 类型为已定义的User模型 数据来源是RequestBody ，根据代码推断，参数是被自动绑定到User中 */
    public String register2(@RequestBody User user) {
        /* 判断用户是否已存在 */
        if (isUsernameExists(user.getUsername())) {
            return "Username already exists";
        }
        try {
            // 手动加载驱动类（可选）
            Class.forName("com.mysql.cj.jdbc.Driver");
            /* 获取mysql链接 */
            try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
                 /* 预编译sql语句 */
                 PreparedStatement stmt = conn.prepareStatement("INSERT INTO users (username, password) VALUES (?, ?)")) {
                /* 使用索引设置绑定两个参数 */
                stmt.setString(1, user.getUsername());
                stmt.setString(2, user.getPassword());
                /* 执行sql语句 */
                stmt.executeUpdate();
                return "Registration successful";
            }
        } catch (SQLException | ClassNotFoundException e) {
            /* 如果捕获到异常，则分析异常原因 */
            return getFailureReason(e);
        }
    }

    /**
     * 异常分析
     * 从这里可以分析出，所有的异常信息都是继承自Exception
     */
    private String getFailureReason(Exception e) {
        /* 如果是sql异常 */
        if (e instanceof SQLException) {
            /* 强制转化类型 */
            SQLException sqlException = (SQLException) e;
            /* 获取异常码 */
            int errorCode = sqlException.getErrorCode();
            /* 状态 */
            String sqlState = sqlException.getSQLState();
            /* 消息 */
            String message = sqlException.getMessage();

            // 常见错误情况处理
            if (errorCode == 1045) { // 数据库连接认证失败
                return "Registration failed: Database authentication error.";
            } else if (errorCode == 1049) { // 数据库不存在
                return "Registration failed: Database does not exist.";
            } else if (errorCode == 1146) { // 表不存在
                return "Registration failed: Table does not exist.";
            } else if (sqlState.startsWith("23")) { // 违反约束条件，如唯一约束
                return "Registration failed: Violation of database constraints.";
            } else {
                // 未知错误，返回详细的异常信息
                return "Registration failed: " + message;
            }
        } else {
            return "Registration failed: " + e.getMessage();
        }
    }

    /**
     * 判断数据库中是否已存在这个用户
     */
    private boolean isUsernameExists(String username) {
        try {
            // 手动加载驱动类（可选） 判断mysql驱动是否存在
            Class.forName("com.mysql.cj.jdbc.Driver");
            /* 获取mysql链接 */
            try (
                    Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
                    /* 预编译sql语句 */
                    PreparedStatement stmt = conn.prepareStatement("SELECT * FROM users WHERE username = ?")
            ) {
                /* 绑定参数 */
                stmt.setString(1, username);
                /* 事务里面套事务 执行sql语句 */
                try (ResultSet rs = stmt.executeQuery()) {
                    /*ResultSet 对象的 next 方法用于将光标移动到结果集的下一行。如果结果集还有下一行，则返回 true，表示找到了匹配的记录；如果没有下一行，则返回 false*/
                    return rs.next();
                }
            }
            /* 捕获异常 包含sql执行异常，或者类没有找到 */
        } catch (SQLException | ClassNotFoundException e) {
            /*打印异常的堆栈跟踪信息，方便调试*/
            e.printStackTrace();
            /*返回 false */
            return false;
        }
    }

    // 注册接口
    @PostMapping("/register")
    public String register(@RequestBody User user) {
        /* 判断是否存在这个用户 */
        if (userDatabase.containsKey(user.getUsername())) {
            return "Username already exists";
        }
        /* 直接写入到内存 */
        userDatabase.put(user.getUsername(), user.getPassword());
        return "Registration successful";
    }

    // 登录接口
    @PostMapping("/login")
    public String login(@RequestBody User user) {
        /* 从内存中获取值 */
        if (userDatabase.containsKey(user.getUsername()) &&

                /* 判断内容是否相同用equals,因为只需要判断内容是否相同，而不是判断是否是同一个对象，如果是判断是否是同一个对象就要用==*/
                userDatabase.get(user.getUsername()).equals(user.getPassword())) {
            return "Login successful";
        }
        return "Invalid username or password";
    }

    @GetMapping("/index")
    public String index() {
        return "Hello World";
    }

    @GetMapping("/say")
    public String say() {
        return "我是say方法";
    }
}